﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Win32;
using System;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using HsServerHa.Utility.DataHelper;
using System.Configuration;

namespace HsServerHa.Utility.Computer
{
    public class RegistryHelper
    { 
        private const string RegistryKeyPath = @"Software\HsServerHa\HsServerHaRegistry";//注册表路径
        public const string key = "THr5MOBP4Yxb9FsSSkS13g==";
        public const string RegisterKey = "hsjm12345678987654321234";
        /// <summary>
        /// 写注册表，提供一对键值
        /// </summary>
        /// <param name="valueName"></param>
        /// <param name="value"></param>
        public static void WriteRegistryValue(string valueName, object value)
        {
            using (RegistryKey key = Registry.CurrentUser.CreateSubKey(RegistryKeyPath))
            {
                key.SetValue(valueName, value);
            }
        }

        /// <summary>
        /// 读注册表，提供一个key值返回对应value
        /// </summary>
        /// <param name="valueName"></param>
        /// <returns></returns>
        public static string ReadRegistryValue(string valueName)
        {
            try
            {
                using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath))
                {
                    if (key != null)
                    {
                        return key.GetValue(valueName)?.ToString();
                    }
                }
            }
            catch { }

            return string.Empty;
        }

        public static string VerifyLicense()
        {

            string savedDate = ReadRegistryValue("License");
            // 检查许可证文件是否存在
            if (savedDate == string.Empty)
            {
                return "许可证不存在！请联系厂家！";
                Environment.Exit(0);

            }

            // 解密许可证密文
            try
            {
                savedDate = DecryptString(savedDate, key);
            }
            catch
            {
                return "许可证解密失败：请联系厂家！"; 
                Environment.Exit(0);
            }

            DateTime cd = DateTime.ParseExact(savedDate, "yyyyMMdd", CultureInfo.InvariantCulture);
            if (string.IsNullOrEmpty(IniFileConfig.Current.GetStringValue("UserConfig", "PCKey")))
            {
                return "许可证不存在！请联系厂家！";
            }
            DateTime hd = DateTime.ParseExact(DecryptString(IniFileConfig.Current.GetStringValue("UserConfig", "PCKey"),key), "yyyyMMdd", CultureInfo.InvariantCulture);

            // 检查系统日期是否小于保存的日期，如果小于说明系统时间被篡改
            if (DateTime.Now < cd)
            {
                return "系统时间被篡改，请检查系统时间设置！";
                 
                Environment.Exit(0);
            }

            if (cd < hd)
            {
                return "许可证时间无效，请联系厂家！";
                Environment.Exit(0);
            }

            // 检查当前日期是否超过硬编码的日期30天，如果超过说明许可证过期
            var day= ConfigurationManager.AppSettings["TestDay"]?.ToInt()??15;
            if (cd > hd.AddDays(day))
            {
                return "许可证已过期：请联系厂家！";
                Environment.Exit(0);
            }
            else
            {
                // 加密当前日期
                string currentDate = EncryptString(DateTime.Now.ToString("yyyyMMdd"), key);

                // 更新许可证密文
                WriteRegistryValue("License", currentDate);
            }

            return string.Empty;
        }

        /// <summary>
        /// 加密字符串，提供一个字符串和密钥，返回一个加密后的字符串
        /// </summary>
        /// <param name="plainText"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string EncryptString(string plainText, string key)
        {
            byte[] encryptedBytes;
            byte[] combinedBytes;
            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.GenerateIV();

                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                        encryptedBytes = msEncrypt.ToArray();
                    }
                }
                // Combine IV and encrypted data
                combinedBytes = new byte[aes.IV.Length + encryptedBytes.Length];
                Array.Copy(aes.IV, 0, combinedBytes, 0, aes.IV.Length);
                Array.Copy(encryptedBytes, 0, combinedBytes, aes.IV.Length, encryptedBytes.Length);
            }
            return Convert.ToBase64String(combinedBytes);
        }

        /// <summary>
        /// 解密字符串，提供一个加密字符串和密钥，返回一个明文字符串
        /// </summary>
        /// <param name="encryptedText"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string DecryptString(string encryptedText, string key)
        {
            byte[] encryptedBytes = Convert.FromBase64String(encryptedText);

            byte[] iv = new byte[16];
            byte[] encryptedData = new byte[encryptedBytes.Length - iv.Length];
            Array.Copy(encryptedBytes, 0, iv, 0, iv.Length);
            Array.Copy(encryptedBytes, iv.Length, encryptedData, 0, encryptedData.Length);

            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = iv;

                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            return srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
        }

    }
  
}
